/*******************************************************************************
 * Copyright (c) 2010 Sylvain Sicard.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Sylvain Sicard - initial API and implementation
 ******************************************************************************/
package com.googlecode.ssdutils.beanconverter.factory;

import java.util.List;
import java.util.Map;

import com.googlecode.ssdutils.beanconverter.api.BeanConverter;
import com.googlecode.ssdutils.beanconverter.api.BeanConverterFactory;
import com.googlecode.ssdutils.beanconverter.asm.ClassGenerator;
import com.googlecode.ssdutils.beanconverter.asm.ConverterClassGeneratorImpl;
import com.googlecode.ssdutils.beanconverter.asm.MemoryClassLoader;


/**
 * @author Sylvain Sicard
 * 
 */
public class BeanConverterFactoryImpl<S, T> implements
		BeanConverterFactory<S, T> {

	private static final String GENERATED_PACKAGE_NAME = "com.googlecode.ssdutils.beanconverter.generated";

	private final ClassGenerator<S, T> asmFactory = new ConverterClassGeneratorImpl<S, T>();

	public void setEntitiesConvertMap(
			Map<String, List<String>> entitiesConvertMap) {
		asmFactory.setEntitiesConvertMap(entitiesConvertMap);
	}

	private final MemoryClassLoader cl = new MemoryClassLoader();

	@SuppressWarnings("unchecked")
	public BeanConverter<S, T> getConverter(Class<S> from, Class<T> to) {

		BeanConverter<S, T> converter = null;
		String converterClassName = GENERATED_PACKAGE_NAME + "." + "Converter"
				+ from.hashCode() * to.hashCode();
		try {
			byte[] code = asmFactory.generateConverterClass(converterClassName,
					from, to);
			Class<BeanConverter<S, T>> c = (Class<BeanConverter<S, T>>) cl
					.defineClass(converterClassName, code);
			converter = c.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return converter;
	}

}
